﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using CsGL.OpenGL;
using CsGL.Util;
using System.Diagnostics;
using System.Collections;

namespace BuildingDrawer
{
    class MyOGLControl : OpenGLControl
    {
        // origin
        public List<E_Point> point_list = new List<E_Point>();
        public List<E_Line> line_list = new List<E_Line>();
        public List<E_Area> area_list = new List<E_Area>();
        public List<E_Solid> solid_list = new List<E_Solid>();
        public List<E_Element> element_list = new List<E_Element>();
        
        //public
        public float scale;
        public float xrot, yrot, zrot;
        public float xtrans, ytrans;
        public bool isOrtho;
        
        // compress
        public E_PointFrame point_frame;
        public E_LineFrame line_frame;
        Boolean isLoadComp = false;

        public MyOGLControl(List<E_Point> point_list, List<E_Line> line_list, List<E_Area> area_list, List<E_Solid> solid_list)
        {
            this.point_list = point_list;
            this.line_list = line_list;
            this.area_list = area_list;
            this.solid_list = solid_list;
            scale = 1f;
            xtrans = 0;
            ytrans = 0;
            zrot = 0;
            isOrtho = false;
            isLoadComp = false;
        }


        public MyOGLControl(List<E_Point> point_list, List<E_Element> element_list)
        {
            this.point_list = point_list;
            this.element_list = element_list;
            scale = 1f;
            xtrans = 0;
            ytrans = 0;
            zrot = 0;
            isOrtho = false;
            isLoadComp = false;
        }

        public MyOGLControl(E_PointFrame point_frame, E_LineFrame line_frame, List<E_Area> area_list, List<E_Solid> solid_list)
        {
            this.point_frame = point_frame;
            this.line_frame = line_frame;
            this.area_list = area_list;
            this.solid_list = solid_list;
            scale = 1f;
            xtrans = 0;
            ytrans = 0;
            zrot = 0;
            isOrtho = false;
            isLoadComp = true;
        }
        public void changeOrtho(bool x)
        {
            isOrtho = x;
        }
        public void ChangeScale(float x)
        {
            this.scale = x;
        }
        public void Changexrot(float x)
        {
            this.xrot = x;
        }
        public void Changeyrot(float x)
        {
            this.yrot = x;
        }
        public void Changezrot(float x)
        {
            this.zrot = x;
        }
        public void Changextrans(float x)
        {
            this.xtrans = x;
        }
        public void Changeytrans(float x)
        {
            this.ytrans = x;
        }
        public void UpdateOGLList(List<E_Point> point_list, List<E_Element>element_list)//update current point_list line_list area_list solid _list
        {
            this.point_list = point_list;
            this.element_list = element_list;
        }
        public void UpdateOGLList(List<E_Point> point_list, List<E_Line> line_list, List<E_Area> area_list, List<E_Solid> solid_list)//update current point_list line_list area_list solid _list
        {
            this.point_list = point_list;
            this.line_list = line_list;
            this.area_list = area_list;
            this.solid_list = solid_list;
        }
        public void UpdateOGLList(E_PointFrame point_frame, E_LineFrame line_frame, List<E_Area> area_list, List<E_Solid> solid_list)
        {
            this.point_frame = point_frame;
            this.line_frame = line_frame;
            this.area_list = area_list;
            this.solid_list = solid_list;
        }
        protected override void InitGLContext()
        {
            base.InitGLContext();
            GL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            GL.glColor3f(255, 0, 0);
            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();

            if (isOrtho)
            {
                GL.glOrtho(3, -3, -3, 3, 0, 100);
            }
            else
            {
                GL.gluPerspective(65.0f, Size.Width / Size.Height, 1.0f, 25.0f);
            }

            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();

            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();

            GL.glViewport(0, 0, Size.Width, Size.Height);
        }
        protected override void OnCreateControl()
        {
            GL.glClearDepth(1.0f);
            GL.glDepthFunc(GL.GL_LEQUAL);
            GL.glEnable(GL.GL_DEPTH_TEST);
        }
        public void changeOthro()
        {

            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();
            if ((Size.Width != 0) && (Size.Height != 0))
            {
                if (isOrtho)
                {
                    GL.glOrtho(3, -3, -3, 3, 0, 100);
                }
                else
                {
                    GL.gluPerspective(65.0f, Size.Width / Size.Height, 1.0f, 25.0f);
                }
            }

            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();
            GL.glViewport(0, 0, this.Size.Width, this.Size.Height);
        }
        protected override void OnSizeChanged(EventArgs e)
        {

            base.OnSizeChanged(e);

            GL.glColor3f(255, 0, 0);
            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();
            if ((Size.Width != 0) && (Size.Height != 0))
            {
                if (isOrtho)
                {
                    GL.glOrtho(3, -3, -3, 3, 0, 100);
                }
                else
                {
                    GL.gluPerspective(65.0f, Size.Width / Size.Height, 1.0f, 25.0f);
                }
            }

            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();
            GL.glViewport(0, 0, this.Size.Width, this.Size.Height);

        }
        public override void glDraw()
        {
            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer 
            GL.glLoadIdentity();


            GL.glTranslatef(0, 0, -10);
            if (isOrtho)
            {
                GL.glTranslatef(-xtrans, ytrans, 0);
            }
            else
            {
                GL.glTranslatef(xtrans, ytrans, 0);
            }

            if (isOrtho)
            {
                GL.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
                GL.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
                GL.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
            }
            else
            {
                GL.glRotatef(-60, 1, 0, 0);
                GL.glRotatef(60, 0, 0, 1);
                GL.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
                GL.glRotatef(yrot, 0.0f, 0.0f, 1.0f);

            }


            GL.glScalef(scale, scale, scale);

            GL.glPushMatrix();

            if (!isLoadComp)
            {
                for (int i = 0; i < line_list.Count; i++)
                {

                    GL.glColor3f(0, 255, 0);
                    GL.glBegin(GL.GL_LINES);
                    GL.glVertex3f(line_list[i].p1.x, line_list[i].p1.y, line_list[i].p1.z);
                    GL.glVertex3f(line_list[i].p2.x, line_list[i].p2.y, line_list[i].p2.z);
                    GL.glEnd();
                }
            }
            else
            {
                if (line_frame == null) { return; }
                foreach (DictionaryEntry de in line_frame.m_line_current)
                {
                    E_Line l = (E_Line)de.Value;
                    E_Point pt1 = point_frame.GetPointFromId(l.p1id);
                    E_Point pt2 = point_frame.GetPointFromId(l.p2id);
                    if (pt1 == null)
                    {
                        pt1 = new E_Point(l.p1id,0,0,0);
                    }
                    if (pt2 == null)
                    {
                        pt2 = new E_Point(l.p2id,0,0,0);
                    }

                    GL.glColor3f(0, 255, 0);
                    GL.glBegin(GL.GL_LINES);
                    GL.glVertex3f(pt1.x, pt1.y, pt1.z);
                    GL.glVertex3f(pt2.x, pt2.y, pt2.z);
                    GL.glEnd();
                }
            }
            for (int i = 0; i < area_list.Count; i++)
            {

                GL.glBegin(GL.GL_LINE_LOOP);
                GL.glColor3f(255, 0, 0);
                GL.glVertex3f(area_list[i].p1.x, area_list[i].p1.y, area_list[i].p1.z);
                GL.glVertex3f(area_list[i].p2.x, area_list[i].p2.y, area_list[i].p2.z);
                GL.glVertex3f(area_list[i].p3.x, area_list[i].p3.y, area_list[i].p3.z);
                GL.glVertex3f(area_list[i].p4.x, area_list[i].p4.y, area_list[i].p4.z);
                GL.glEnd();

            }
           
            for (int i = 0; i < element_list.Count; i++)
            {
                switch (element_list[i].type)
                {
                    case 1:
                        {
                            E_Bar eb = (E_Bar)element_list[i];

                            GL.glColor3f(0, 255, 0);
                            GL.glBegin(GL.GL_LINES);
                            GL.glVertex3f(eb.p1.x, eb.p1.y, eb.p1.z);
                            GL.glVertex3f(eb.p2.x, eb.p2.y, eb.p2.z);
                            GL.glEnd();
                            break;
                        }
                    case 2:
                        {
                            E_Plat ep = (E_Plat)element_list[i];
                            GL.glBegin(GL.GL_LINE_LOOP);
                            GL.glColor3f(255, 0, 0);
                            for (int k = 0; k < ep.NodeArray.Count; k++)
                            {
                                GL.glVertex3f(ep.NodeArray[k].x, ep.NodeArray[k].y, ep.NodeArray[k].z);

                            }
                            GL.glEnd();

                            
                            GL.glEnable(GL.GL_BLEND);
                            GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_DST_COLOR);
                            GL.glBegin(GL.GL_POLYGON);
                            
                            GL.glColor4f(0, 0, 255, 0.5f);
                            for (int k = 0; k < ep.NodeArray.Count; k++)
                            {
                                GL.glVertex3f(ep.NodeArray[k].x, ep.NodeArray[k].y, ep.NodeArray[k].z);

                            }
                            GL.glEnd();
                            GL.glDisable(GL.GL_BLEND);
                           

                            break;
                        }
                    default:
                        break;
                }
            }
                for (int i = 0; i < solid_list.Count; i++)
                {
                    GL.glColor3f(0, 0, 255);
                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a1.p1.x, solid_list[i].a1.p1.y, solid_list[i].a1.p1.z);
                    GL.glVertex3f(solid_list[i].a1.p2.x, solid_list[i].a1.p2.y, solid_list[i].a1.p2.z);
                    GL.glVertex3f(solid_list[i].a1.p3.x, solid_list[i].a1.p3.y, solid_list[i].a1.p3.z);
                    GL.glVertex3f(solid_list[i].a1.p4.x, solid_list[i].a1.p4.y, solid_list[i].a1.p4.z);
                    GL.glEnd();

                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a2.p1.x, solid_list[i].a2.p1.y, solid_list[i].a2.p1.z);
                    GL.glVertex3f(solid_list[i].a2.p2.x, solid_list[i].a2.p2.y, solid_list[i].a2.p2.z);
                    GL.glVertex3f(solid_list[i].a2.p3.x, solid_list[i].a2.p3.y, solid_list[i].a2.p3.z);
                    GL.glVertex3f(solid_list[i].a2.p4.x, solid_list[i].a2.p4.y, solid_list[i].a2.p4.z);
                    GL.glEnd();

                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a3.p1.x, solid_list[i].a3.p1.y, solid_list[i].a3.p1.z);
                    GL.glVertex3f(solid_list[i].a3.p2.x, solid_list[i].a3.p2.y, solid_list[i].a3.p2.z);
                    GL.glVertex3f(solid_list[i].a3.p3.x, solid_list[i].a3.p3.y, solid_list[i].a3.p3.z);
                    GL.glVertex3f(solid_list[i].a3.p4.x, solid_list[i].a3.p4.y, solid_list[i].a3.p4.z);
                    GL.glEnd();

                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a4.p1.x, solid_list[i].a4.p1.y, solid_list[i].a4.p1.z);
                    GL.glVertex3f(solid_list[i].a4.p2.x, solid_list[i].a4.p2.y, solid_list[i].a4.p2.z);
                    GL.glVertex3f(solid_list[i].a4.p3.x, solid_list[i].a4.p3.y, solid_list[i].a4.p3.z);
                    GL.glVertex3f(solid_list[i].a4.p4.x, solid_list[i].a4.p4.y, solid_list[i].a4.p4.z);
                    GL.glEnd();

                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a5.p1.x, solid_list[i].a5.p1.y, solid_list[i].a5.p1.z);
                    GL.glVertex3f(solid_list[i].a5.p2.x, solid_list[i].a5.p2.y, solid_list[i].a5.p2.z);
                    GL.glVertex3f(solid_list[i].a5.p3.x, solid_list[i].a5.p3.y, solid_list[i].a5.p3.z);
                    GL.glVertex3f(solid_list[i].a5.p4.x, solid_list[i].a5.p4.y, solid_list[i].a5.p4.z);
                    GL.glEnd();

                    GL.glBegin(GL.GL_LINE_LOOP);
                    GL.glVertex3f(solid_list[i].a6.p1.x, solid_list[i].a6.p1.y, solid_list[i].a6.p1.z);
                    GL.glVertex3f(solid_list[i].a6.p2.x, solid_list[i].a6.p2.y, solid_list[i].a6.p2.z);
                    GL.glVertex3f(solid_list[i].a6.p3.x, solid_list[i].a6.p3.y, solid_list[i].a6.p3.z);
                    GL.glVertex3f(solid_list[i].a6.p4.x, solid_list[i].a6.p4.y, solid_list[i].a6.p4.z);
                    GL.glEnd();

                }

            //坐标轴是一根直线加一个四面体 四面体是由4个三角形组成的

                float axis_length = 1;
                float arrow_size=0.02f;
                GL.glColor3f(0, 255, 255);
            //1st
                GL.glBegin(GL.GL_LINES);
                GL.glVertex3f(0, 0, 0);
                GL.glVertex3f(axis_length, 0, 0);
                GL.glEnd();

                GL.glBegin(GL.GL_TRIANGLES);
                GL.glVertex3f(axis_length, arrow_size*(-1), arrow_size*(-1.67f));
                GL.glVertex3f(axis_length, arrow_size * (-1), arrow_size * (1.67f));
                GL.glVertex3f(axis_length, arrow_size * (1.67f), 0);

                GL.glVertex3f(axis_length+arrow_size * 6, 0, 0);
                GL.glVertex3f(axis_length, arrow_size * (-1), arrow_size * (1.67f));
                GL.glVertex3f(axis_length, arrow_size * (1.67f), 0);

                GL.glVertex3f(axis_length, arrow_size * (-1), arrow_size * (-1.67f));
                GL.glVertex3f(axis_length + arrow_size * 6, 0, 0);
                GL.glVertex3f(axis_length, arrow_size * (1.67f), 0);

                GL.glVertex3f(axis_length, arrow_size * (-1), arrow_size * (-1.67f));
                GL.glVertex3f(axis_length, arrow_size * (-1), arrow_size * (1.67f));
                GL.glVertex3f(axis_length + arrow_size * 6, 0, 0);
                GL.glEnd();
            //2nd
                GL.glBegin(GL.GL_LINES);
                GL.glVertex3f(0, 0, 0);
                GL.glVertex3f(0, axis_length, 0);
                GL.glEnd();

                GL.glBegin(GL.GL_TRIANGLES);
                GL.glVertex3f( arrow_size * (-1),axis_length, arrow_size * (-1.67f));
                GL.glVertex3f( arrow_size * (-1),axis_length, arrow_size * (1.67f));
                GL.glVertex3f( arrow_size * (1.67f),axis_length, 0);

                GL.glVertex3f( 0,axis_length + arrow_size * 6, 0);
                GL.glVertex3f( arrow_size * (-1),axis_length, arrow_size * (1.67f));
                GL.glVertex3f( arrow_size * (1.67f),axis_length, 0);

                GL.glVertex3f( arrow_size * (-1),axis_length, arrow_size * (-1.67f));
                GL.glVertex3f(0,axis_length + arrow_size * 6, 0);
                GL.glVertex3f(arrow_size * (1.67f),axis_length,  0);

                GL.glVertex3f(arrow_size * (-1),axis_length,  arrow_size * (-1.67f));
                GL.glVertex3f(arrow_size * (-1),axis_length,  arrow_size * (1.67f));
                GL.glVertex3f( 0,axis_length + arrow_size * 6, 0);
                GL.glEnd();


            //3rd
                GL.glBegin(GL.GL_LINES);
                GL.glVertex3f(0, 0, 0);
                GL.glVertex3f(0, 0, axis_length);
                GL.glEnd();
                GL.glBegin(GL.GL_TRIANGLES);
                GL.glVertex3f(arrow_size * (-1), arrow_size * (-1.67f), axis_length);
                GL.glVertex3f(arrow_size * (-1), arrow_size * (1.67f), axis_length);
                GL.glVertex3f(arrow_size * (1.67f), 0, axis_length);

                GL.glVertex3f(0, 0, axis_length + arrow_size * 6);
                GL.glVertex3f(arrow_size * (-1), arrow_size * (1.67f), axis_length);
                GL.glVertex3f(arrow_size * (1.67f), 0, axis_length);

                GL.glVertex3f(arrow_size * (-1), arrow_size * (-1.67f), axis_length);
                GL.glVertex3f(0, 0, axis_length + arrow_size * 6);
                GL.glVertex3f(arrow_size * (1.67f), 0, axis_length);

                GL.glVertex3f(arrow_size * (-1), arrow_size * (-1.67f), axis_length);
                GL.glVertex3f(arrow_size * (-1), arrow_size * (1.67f), axis_length);
                GL.glVertex3f(0, 0, axis_length + arrow_size * 6);
                GL.glEnd();

            GL.glPopMatrix(); //当前操作矩阵出栈


            GL.glFlush(); //强制绘图完成
        }
    }
}
